<?php
	require_once(dirname(__FILE__)."/incluir.php");
	// Classe que define os templates dos casos de uso de um viale genérico
	class EntidadeTemplate
	{
		// Informações da tabela do banco de dados
		protected $model;
		protected $fields;
		protected $campos;
		protected $nome_controller;
		
		// Informações sobre como ordernar e paginar
		protected $get;
		protected $sufixo;
		
		// O contrutor precisa de uma instancia de Model ou de uma classe derivada, do get e de um sufixo para os nomes dos campos
		public function __construct($model, $get)
		{
			$this->model = $model;
			$this->fields = $model->fields;
			$this->campos = $model->campos;
			
			$this->get = $get;		
			$this->sufixo = $model->sufixo;
			// Guarda o nome da variavel que controlará as páginas do viale
			$this->nome_controller = '$'.$model->tabela.'_controller';
		}
		
		// Funções auxiliares (funções privadas/protected)
		
		protected function salva_template($filename, $valor)
		{
			$path = './templates/' . $filename;
			file_put_contents($path, $valor);
		}
		
		protected function append_output(&$output,$value)
		{
			$output .= $value;
			$output .= "\n";
		}
		
		protected function gera_array_ordem_campos()
		{
			$output .= '$ordem_campos = array(';
			$first = true;
			foreach($this->fields as $field)
			{
				$campo = $this->model->campos[$field];
				if(!in_array("index", $campo->paginas_aparece)) continue;
				if($first)
				{
					$output .= "'$field'";
					$first = false;
				}
				else
				{
					$output .= ", '$field'";
				}
			}
			$output .= ');';
			return $output;
		}
		
		// Escreve o php inicial do template gerenciar
		protected function print_header_gerenciar(&$output)
		{
			$this->append_output($output,	'<?php ');
			$this->append_output($output,	"\t".'$pagination = $site->paginacao->paginate($_GET, $tabela, $limit, '.$this->nome_controller.'->model->fields, $offset_default);	// Pega dados paginados por GET');
			$this->append_output($output,	"\t".'$order_aux = ($_GET["order"] == 0) ? 1 : 0; // Inverte a ordem, se estava vendo crescente, passará a ver decrescente');
			$this->append_output($output,	"\t".'$indice_linha = 0; // variável que servirá para saber se a linha é par ou se a linha é impar');
			$this->append_output($output,	"\t".$this->gera_array_ordem_campos());
			$this->append_output($output,	'?>');
		}		
		
		// Gera a head da table do caso de uso gerenciar 
		protected function gerenciar_header()
		{
			$output = '';
			$this->append_output($output, '<tr>');
			foreach($this->fields as $field)
			{
				//Se o campo não deve ser mostrado passa para o próximo, ou seja , se a página index não está no array de paginas do campo
				$campo = $this->campos[$field];
				if(!in_array('index', $campo->paginas_aparece)) continue;
				
				$this->append_output($output, '<th>');
				
				// A label ou será a que foi dita em dados.php ou é o nome do campo com a primeira letra maiúscula
				$label = $campo->label;
				
				$this->append_output($output, "\t".'<a href="./?orderBy='.$field.'&amp;order=<?php echo $order_aux; ?>">'.$label.'</a>');
				
				$this->append_output($output, '</th>');
			}
			$this->append_output($output, '<th colspan="2">Opções</th>');
			$this->append_output($output, '</tr>');
			return $output;
		}
		
		
		
		// Gera o body da table do caso de uso gerenciar
		protected function gerenciar_body()
		{
			$output = '';
			$this->append_output($output, "\t".'<?php foreach($pagination["rows"] as $row): // Escreve o corpo da tabela, $pagination["rows"] vale todos os registros da tabela desse viale ?>');
			$this->append_output($output, "\t".'<?php $classe = ($indice_linha % 2 == 0) ? "par" : "impar"; // Decide se a classe da linha da tabela será par ou se será impar ?>');
			$this->append_output($output, "\t\t".'<tr class="<?php echo $classe?>">');
			$this->append_output($output, "\t\t".'<?php foreach($ordem_campos as $field): ?>');
			$this->append_output($output, "\t\t".'<?php $value = $row[$field];?>');
			$this->append_output($output, "\t\t".'<?php if($field == $referencia): // Se for igual, deve ser um link para visualizar esse elemento ?>');
			$this->append_output($output, "\t\t\t".'<td><a href="./visualizar.php?id=<?php echo $row["id"];?>"><?php echo $value;?></a></td>');
			$this->append_output($output, "\t\t".'<?php else:?>');
			$this->append_output($output, "\t\t\t".'<td><?php echo $value; ?></td>');
			$this->append_output($output, "\t\t".'<?php endif;?>');
			$this->append_output($output, "\t\t".'<?php endforeach;?>');
			$this->append_output($output, "\t\t".'<td><a href="./alterar.php?id=<?php echo $row["id"];?>">Alterar</a></td>');
			$this->append_output($output, "\t\t".'<td><a href="./excluir.php?id=<?php echo $row["id"];?>"');
			$this->append_output($output, "\t\t"."onclick=\"javascript: return confirm('Tem certeza que deseja excluir" . ' <?php echo $row[$referencia];?>' . "');\"". '>Excluir</a></td>');
			$this->append_output($output, "\t\t".'</tr>');
			$this->append_output($output, "\t\t".'<?php $indice_linha++; // Incrementa indice_linha, a variavel que ajuda a alternar as classes das linhas ?>');
			$this->append_output($output, "\t".'<?php endforeach;?>');
			return $output;
		}
		
		// Actions (funções públicas)
		
		// $criar_template diz obrigatóriamente se é para criar o template, mesmo se existir
		public function tabela_gerenciar($criar_template = false, $referencia_val = null) 
		{
			if($criar_template == true || !file_exists('./templates/gerenciar.php'))
			{	
				$output = '';
				
				// Crio o php que pegará as informações no template
				$this->print_header_gerenciar($output);
				
				$this->append_output($output, '<table class="index" border="1px">');
				$this->append_output($output, '<thead>');
				$this->append_output($output, $this->gerenciar_header());
				$this->append_output($output, '</thead>');
				
				$this->append_output($output, '<tbody>');
				$this->append_output($output, $this->gerenciar_body());	
				$this->append_output($output, '</tbody>');
				 
				$this->append_output($output, '</table>');
				
				$this->append_output($output, '<div>');
				$this->append_output($output, "\t".'<?php echo $site->paginacao->show_pages($pagination["params"], $limit, $range); // $pagination["params"] contém dados para saber páginar, como order e orderby ?>');
				$this->append_output($output, '</div>');
				
				$this->salva_template('gerenciar.php', $output);
				
				return $output;
			}
		}
		
		// Escreve o php inicial do template visualizar
		protected function print_header_visualizar(&$output)
		{
			$this->append_output($output,	'<?php ');
			$this->append_output($output,	"\t".'$row = '.$this->nome_controller.'->model->get_row();');
			$this->append_output($output,	'?>');
		}
		
		// $criar_template diz obrigatóriamente se é para criar o template, mesmo se existir
		public function visualizar($criar_template = false) //Vê os campos de um elemento passado
		{
			$output = '';
			
			if($criar_template == true || !file_exists('./templates/visualizar.php'))
			{
				// Crio o php que pegará as informações no template
				$this->print_header_visualizar($output);	
				$this->append_output($output,  '<div id="informacoes">');
				foreach($this->model->fields as $field)
				{
					//Se o campo não deve ser mostrado passa para o próximo
					$campo = $this->model->campos[$field];
					if(!in_array('visualizar', $campo->paginas_aparece)) continue;
					
					if($campo->tipo == "select") // Se esse campo é para relacionar com outra tabela (exemplo: gerente_id)
					{
						$this->append_output($output,  '<?php '.$this->nome_controller.'->model->campos["'.$field.'"]->visualizar($row["'.$field.'"]); // Mostra os valores de outra tabela de relacionamento (exemplo: a linha da tabela gerente com o id gerente_id)?>');
					}
					else if($campo->tipo == "checkbox")
					{
						$this->append_output($output,  '<?php '.$this->nome_controller.'->model->campos["'.$field.'"]->visualizar($row["'.$field.'"]); // Mostra o valor real e não o valor que está no banco(normalmente um número) ?>');
					}
					else if($campo->tipo == "radio")
					{
						$this->append_output($output,  '<?php '.$this->nome_controller.'->model->campos["'.$field.'"]->visualizar($row["'.$field.'"]); // Mostra o valor real e não o valor que está no banco(normalmente um número) ?>');
					}
					else if($campo->tipo == "data")
					{
						$this->append_output($output,  '<span class="label_campo"> '.$campo->label.':</span><span class="valor_campo"><?php echo $site->data_normal($row["'.$field.'"]); //Converte a data do banco a data normal: dd/mm/aaaa ?></span><br />');
					}
					// Se o campo tiver sido preenchido por uma textarea, os seus \n tem que ser substituidos por tags <br />, para mostrar corretamente o seu valor
					else if($campo->tipo == "textarea")
					{
						$this->append_output($output,  '$valor = str_replace("\n", "<br />", $valor);');
						$this->append_output($output,  '<span class="label_campo"> '.$campo->label.':</span><br/><span class="valor_campo"><?php echo $row["'.$field.'"]; ?></span><br />');
					}
					else
					{
						$this->append_output($output,  '<span class="label_campo"> '.$campo->label.':</span><span class="valor_campo"><?php echo $row["'.$field.'"]; ?></span><br />');
					}
				}
				$this->append_output($output, '</div>');
				
				$this->salva_template('visualizar.php', $output);
				
				return $output;
			}
		}
		
		// Os campos serão gerados da mesma maneira para os dois casos de uso
		// O parametro $funcionalidade valerá inserir ou alterar
		protected function print_campos_inserir_alterar($funcionalidade, $criar_template = false)
		{
			$output = ''; // string que conterá todo o template do caso de uso
			$file = "$funcionalidade.php"; // qual arquivo representa o template da função
			
			// Se não existe o template ou se quem chamou essa classe explicitou, cria os campos da entidade
			if($criar_template == true || !file_exists("./templates/$file"))
			{
				// Escreve os campos
				foreach($this->model->campos as $field => $campo)
				{
					if(!in_array($funcionalidade, $campo->paginas_aparece)) continue;
					
					$campo->label = $campo->label.": "; // ajeita a label colocando nela um dois pontos e um espaço
					
					// O valor de um campo select que depende de outra tabela pode mudar constantemente
					// Então eu coloco um codigo php que sempre irá gerar esse select
					if($campo->tipo == "select" && $campo->tabela != $this->model->tabela)
					{
						// Funciona também para um campo select que tem valores pré-definidos
						$this->append_output($output,
						'<?php '.$this->nome_controller.'->model->campos["'.$field.'"]->escreve_html_select(true, true, false, null, false, '.$this->nome_controller.'->model->'.$field.'); ?>');
						// Coloca o erro do campo
						$this->append_output($output, '<?php $site->print_erro('.$this->nome_controller.'->erros["'.$field.'"]);?>'."\n");
					}
					// Se for um select com valores fixos, adiciona o seu html
					else if($campo->tipo == "select" && $campo->tabela == $this->model->tabela)
					{
						$this->append_output($output,
						'<?php '.$this->nome_controller.'->model->campos["'.$field.'"]->escreve_html_select(true, true, false, null, false, '.$this->nome_controller.'->model->'.$field.'); ?>');
						// Coloca o erro do campo
						$this->append_output($output, '<?php $site->print_erro('.$this->nome_controller.'->erros["'.$field.'"]);?>'."\n");
					}
					
					else if($campo->tipo == "checkbox")
					{
						$this->append_output($output,
						'<?php '.$this->nome_controller.'->model->campos["'.$field.'"]->escreve_html_checkbox(true, true, false, null, '.$this->nome_controller.'->model->'.$field.'); ?>');
						// Coloca o erro do campo
						$this->append_output($output, '<?php $site->print_erro('.$this->nome_controller.'->erros["'.$field.'"]);?>'."\n");
					}
					else if($campo->tipo == "radio")
					{
						$this->append_output($output,
						'<?php '.$this->nome_controller.'->model->campos["'.$field.'"]->escreve_html_radio(true, true, false, null, '.$this->nome_controller.'->model->'.$field.'); ?>');
						// Coloca o erro do campo
						$this->append_output($output, '<?php $site->print_erro('.$this->nome_controller.'->erros["'.$field.'"]);?>'."\n");
					}
					else
					{
						//$escreve_na_tela = false, ou seja irá retornar o código html do campo como string, sem dar echo nesse código
						$this->append_output($output, $campo->escreve_html(false));
					}
				}

				// Inclui o botão de submit. 
				// O id do submit é a tabela do model
				$this->append_output($output, '<br /><input id="'.$this->model->tabela.'" type="submit" value="'.ucfirst($funcionalidade).'" />'); 
				
				$this->salva_template($file, $output);
				
				return $output;
			}
		}
		
		// Recebo o viale para escrever as informações dos seus campos
		// $criar_template diz obrigatóriamente se é para criar o template, mesmo se existir
		public function print_campos_inserir($criar_template = false)
		{	
			$funcionalidade = 'inserir'; // Qual o caso de uso
			return $this->print_campos_inserir_alterar($funcionalidade, $criar_template);		
		}
		
		// $criar_template diz obrigatóriamente se é para criar o template, mesmo se existir
		public function print_campos_alterar($criar_template = false)
		{	
			$funcionalidade = 'alterar'; // Qual o caso de uso
			return $this->print_campos_inserir_alterar($funcionalidade, $criar_template);	
		}	
	}
?>